#include "CollaborationManager.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QUuid>
#include <QDebug>
#include <QUrl>

namespace CollaborativeDesign {

CollaborationManager::CollaborationManager()
    : QObject(nullptr),
      m_serverUrl("ws://localhost:8080/collaboration"),
      m_currentSessionId("")
{
    // 初始化WebSocket
    initWebSocket();
}

CollaborationManager::~CollaborationManager()
{
    // 断开WebSocket连接
    if (m_webSocket.isValid()) {
        m_webSocket.close();
    }
}

bool CollaborationManager::initSession(const QString& sessionId)
{
    // 检查会话是否存在
    if (!m_sessions.contains(sessionId)) {
        qWarning() << "会话不存在:" << sessionId;
        return false;
    }
    
    // 设置当前会话ID
    m_currentSessionId = sessionId;
    
    // 发送会话初始化消息
    QJsonObject message;
    message["type"] = "init_session";
    message["session_id"] = sessionId;
    message["user_id"] = m_currentUser.id;
    
    m_webSocket.sendTextMessage(QJsonDocument(message).toJson());
    
    // 发送会话状态变更信号
    emit sessionStatusChanged(sessionId, "initialized");
    
    qDebug() << "初始化会话:" << sessionId;
    return true;
}

bool CollaborationManager::joinSession(const QString& sessionId, const QString& userId)
{
    // 检查会话是否存在
    if (!m_sessions.contains(sessionId)) {
        qWarning() << "会话不存在:" << sessionId;
        return false;
    }
    
    // 检查用户是否存在
    if (!m_users.contains(userId)) {
        qWarning() << "用户不存在:" << userId;
        return false;
    }
    
    // 将用户添加到会话
    Session& session = m_sessions[sessionId];
    if (!session.userIds.contains(userId)) {
        session.userIds.append(userId);
    }
    
    // 发送用户加入消息
    QJsonObject message;
    message["type"] = "join_session";
    message["session_id"] = sessionId;
    message["user_id"] = userId;
    
    m_webSocket.sendTextMessage(QJsonDocument(message).toJson());
    
    // 发送用户加入信号
    emit userJoined(sessionId, m_users[userId]);
    
    qDebug() << "用户加入会话:" << userId << "->" << sessionId;
    return true;
}

bool CollaborationManager::leaveSession(const QString& sessionId, const QString& userId)
{
    // 检查会话是否存在
    if (!m_sessions.contains(sessionId)) {
        qWarning() << "会话不存在:" << sessionId;
        return false;
    }
    
    // 从会话中移除用户
    Session& session = m_sessions[sessionId];
    session.userIds.removeAll(userId);
    
    // 发送用户离开消息
    QJsonObject message;
    message["type"] = "leave_session";
    message["session_id"] = sessionId;
    message["user_id"] = userId;
    
    m_webSocket.sendTextMessage(QJsonDocument(message).toJson());
    
    // 发送用户离开信号
    emit userLeft(sessionId, userId);
    
    qDebug() << "用户离开会话:" << userId << "->" << sessionId;
    return true;
}

QList<User> CollaborationManager::getSessionUsers(const QString& sessionId)
{
    QList<User> users;
    
    // 检查会话是否存在
    if (!m_sessions.contains(sessionId)) {
        qWarning() << "会话不存在:" << sessionId;
        return users;
    }
    
    // 获取会话中的用户
    const Session& session = m_sessions[sessionId];
    for (const QString& userId : session.userIds) {
        if (m_users.contains(userId)) {
            users.append(m_users[userId]);
        }
    }
    
    return users;
}

bool CollaborationManager::sendChange(const Change& change)
{
    // 验证变更
    if (!validateChange(change)) {
        qWarning() << "变更验证失败";
        return false;
    }
    
    // 处理变更
    handleChange(change);
    
    // 广播变更
    broadcastChange(change);
    
    return true;
}

User CollaborationManager::getCurrentUser() const
{
    return m_currentUser;
}

void CollaborationManager::setCurrentUser(const User& user)
{
    m_currentUser = user;
}

QList<Session> CollaborationManager::getAllSessions()
{
    return m_sessions.values();
}

Session CollaborationManager::createSession(const QString& name)
{
    // 创建新会话
    Session session;
    session.id = QUuid::createUuid().toString(QUuid::WithoutBraces);
    session.name = name;
    session.createTime = QDateTime::currentDateTime();
    
    // 添加当前用户到会话
    if (!m_currentUser.id.isEmpty()) {
        session.userIds.append(m_currentUser.id);
    }
    
    // 添加到会话映射表
    m_sessions[session.id] = session;
    
    // 发送会话创建消息
    QJsonObject message;
    message["type"] = "create_session";
    message["session_id"] = session.id;
    message["session_name"] = session.name;
    message["user_id"] = m_currentUser.id;
    
    m_webSocket.sendTextMessage(QJsonDocument(message).toJson());
    
    // 发送会话状态变更信号
    emit sessionStatusChanged(session.id, "created");
    
    qDebug() << "创建会话:" << session.id << "-" << session.name;
    return session;
}

void CollaborationManager::onConnected()
{
    qDebug() << "WebSocket连接成功";
    
    // 发送认证消息
    QJsonObject message;
    message["type"] = "auth";
    message["user_id"] = m_currentUser.id;
    message["user_name"] = m_currentUser.name;
    
    m_webSocket.sendTextMessage(QJsonDocument(message).toJson());
}

void CollaborationManager::onDisconnected()
{
    qDebug() << "WebSocket连接断开";
    
    // 尝试重新连接
    QTimer::singleShot(5000, this, [this]() {
        m_webSocket.open(QUrl(m_serverUrl));
    });
}

void CollaborationManager::onTextMessageReceived(const QString& message)
{
    // 解析JSON消息
    QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
    if (doc.isNull() || !doc.isObject()) {
        qWarning() << "无效的JSON消息";
        return;
    }
    
    QJsonObject obj = doc.object();
    QString type = obj["type"].toString();
    
    if (type == "change") {
        // 处理变更消息
        Change change;
        change.id = obj["change_id"].toString();
        change.userId = obj["user_id"].toString();
        change.filePath = obj["file_path"].toString();
        change.data = obj["data"].toObject();
        change.timestamp = QDateTime::fromString(obj["timestamp"].toString(), Qt::ISODate);
        
        // 发送变更接收信号
        emit changeReceived(change);
        
        // 处理变更
        handleChange(change);
    }
    else if (type == "user_joined") {
        // 处理用户加入消息
        QString sessionId = obj["session_id"].toString();
        QString userId = obj["user_id"].toString();
        
        // 更新用户信息
        if (obj.contains("user")) {
            QJsonObject userObj = obj["user"].toObject();
            User user;
            user.id = userId;
            user.name = userObj["name"].toString();
            user.avatar = userObj["avatar"].toString();
            user.online = true;
            user.currentFile = userObj["current_file"].toString();
            
            // 更新用户映射表
            m_users[userId] = user;
            
            // 发送用户加入信号
            emit userJoined(sessionId, user);
        }
    }
    else if (type == "user_left") {
        // 处理用户离开消息
        QString sessionId = obj["session_id"].toString();
        QString userId = obj["user_id"].toString();
        
        // 发送用户离开信号
        emit userLeft(sessionId, userId);
    }
    else if (type == "session_update") {
        // 处理会话更新消息
        QString sessionId = obj["session_id"].toString();
        QString status = obj["status"].toString();
        
        // 发送会话状态变更信号
        emit sessionStatusChanged(sessionId, status);
    }
}

void CollaborationManager::initWebSocket()
{
    // 连接WebSocket信号
    connect(&m_webSocket, &QWebSocket::connected, this, &CollaborationManager::onConnected);
    connect(&m_webSocket, &QWebSocket::disconnected, this, &CollaborationManager::onDisconnected);
    connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &CollaborationManager::onTextMessageReceived);
    
    // 连接到服务器
    m_webSocket.open(QUrl(m_serverUrl));
}

void CollaborationManager::handleChange(const Change& change)
{
    // 添加到待处理变更列表
    m_pendingChanges.append(change);
    
    // 实际应用中，这里应该根据变更类型执行不同的操作
    // 例如，更新文件内容、移动光标位置等
    
    qDebug() << "处理变更:" << change.id << "-" << change.filePath;
}

void CollaborationManager::broadcastChange(const Change& change)
{
    // 发送变更消息
    QJsonObject message;
    message["type"] = "change";
    message["change_id"] = change.id;
    message["user_id"] = change.userId;
    message["file_path"] = change.filePath;
    message["data"] = change.data;
    message["timestamp"] = change.timestamp.toString(Qt::ISODate);
    message["session_id"] = m_currentSessionId;
    
    m_webSocket.sendTextMessage(QJsonDocument(message).toJson());
    
    qDebug() << "广播变更:" << change.id;
}

bool CollaborationManager::validateChange(const Change& change)
{
    // 检查变更是否有效
    if (change.id.isEmpty() || change.userId.isEmpty() || change.filePath.isEmpty()) {
        return false;
    }
    
    // 检查用户是否有权限
    // 实际应用中，这里应该检查用户对文件的权限
    
    return true;
}

} // namespace CollaborativeDesign 